#
# F E M - Fuckuped Encrypted Messanger
#
#                                by ch4se


#[ FEM-server ]


import socket
import os


server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server_socket.bind(("localhost", 23523))
server_socket.listen()




#[]=====[основные функции подключения и тд]=====[]#


def connect():
    print("\nжду подключения собеседника...")
    socket_data, addr = server_socket.accept()
    print("подключено! отправляю секретный вопрос...", str(addr))
    return socket_data


def verify():
    question = get_question()
    socket_data.sendall(bytes(question, "utf-8"))
    answer = socket_data.recv(1024).decode()
    print("полученный ответ: ", answer)
    print("правильный ответ: ", get_answer(), "\n")
    choose = input("[разрешить подключение? y/n]==> ")

    if choose == "y":
        socket_data.send(bytes("0", "utf-8"))
    elif choose ==  "n":
        socket_data.sendall(bytes("1", "utf-8"))
        exit(0)
    else:
        exit(0)



def chat():
    while 1:
        mes_recv = socket_data.recv(1024)

        #записываем в файл полученное зашифрованное сообщение
        friend_file = open("friend","wb")
        friend_file.write(mes_recv)
        friend_file.close()
        
        
        #расшифровываем то что записали в файл friend с помощью нашего приватного ключа
        os.system("openssl pkeyutl -decrypt -inkey session -in friend -out friend_decrypt.txt")


        #читаем из friend_decrypt.txt расшифрованное сообщение и выводим его!
        firend_file1 = open("friend_decrypt.txt","r")
        finally_mes = firend_file1.read()
        firend_file1.close()
        print(finally_mes)
        
        mes = input("[введите сообщение]==> ")
        mes = mes + ' [~]от ' + get_name()
        

        #записываем текст нашего сообщения в файл
        mes_file = open("mes.txt","w")
        mes_file.write(mes)
        mes_file.close()

        #шифруем файл открытым ключом друга
        os.system("openssl pkeyutl -encrypt -pubin -inkey friend.public -in mes.txt -out en_mes")

        #читаем из уже зашифрованного файла
        enmes_file = open("en_mes","rb")
        en_mes = enmes_file.read()
        enmes_file.close()
        
        #отправляем зашифрованное сообщение
        socket_data.sendall(en_mes)



def gen_session_keys():
    print("сейчас будет сгенерирована пара ключей для зашифрованного общения!")
    print("\n")
    os.system("bash FEM-gen_session_keys.sh")
    print("ключи успешно сгенерированы!")



def recv_public_key():
    print("\nсейчас будет произведен обмен открытыми ключами...")
    pub = open("session.public","r")                                                                               
    pub_send = pub.read()                                                                                        
    pub.close()
    socket_data.sendall(bytes(pub_send,"utf-8"))
    print("ваш открытый ключ отправлен! ждем ключ собеседника...")
    friend_pub = socket_data.recv(1024).decode()
    print("\nключ собеденика получен!\n",friend_pub)

    friend_file = open("friend.public","w")
    friend_file.write(friend_pub)
    friend_file.close()



#[]=========================================[]#



#[]============[set,get функции]============[]#


def get_question():
    question_file = open("config/question.txt","r")
    question = question_file.read()
    question_file.close()
    return str(question)


def set_question():
    print("\n[изменение вопроса]")
    print("текущий вопрос: ", get_question())
    new_question = str(input("[введите новый вопрос]==> "))
    question_file = open("config/question.txt","w")
    new_question = new_question + "\n"
    question_file.write(new_question)
    question_file.close()
    print("вопрос успешно изменен ;)")


def get_answer():
    answer_file = open("config/answer.txt","r")
    answer = answer_file.read()
    answer_file.close()
    return str(answer)


def set_answer():
    print("\n[изменение ответа]")
    print("текущий ответ: ", get_answer())
    new_answer = str(input("[введите новый ответ]==> "))
    answer_file = open("config/answer.txt","w")
    new_answer = new_answer + "\n"
    answer_file.write(new_answer)
    answer_file.close()
    print("ответ успешно изменен ;)")


def get_name():
    name_file = open("config/name.txt","r")
    name = name_file.read()
    name_file.close()
    return str(name)


def set_name():
    print("\n[изменение имени]")
    print("текущее имя: ", get_name())
    new_name = str(input("[введите новое имя]==> "))
    name_file = open("config/name.txt","w")
    new_name = new_name + "\n"
    name_file.write(new_name)
    name_file.close()
    print("имя успешно изменено ;)")


#[]=========================================[]#



#[]=======[меню выбора, логотип и тд]=======[]#


os.system("clear && echo 'FEM-server' | figlet | lolcat")
os.system("echo '                                                 by ch4se' | lolcat")


print("[1] - начать ожидание подключения ")                                                                       
print("[2] - изменить вопрос ")                                                                 
print("[3] - изменить ответ ")
print("[4] - изменить имя ")
print("\n")                                                                                                       

choose = int(input("[?]==> "))                                                                                    
if choose == 1:
    socket_data = connect()  
    verify()
    gen_session_keys()
    recv_public_key()
    print("соеденение установлено! ждем первое сообщение от клиента...")
    chat()

elif choose == 2:
    set_question()

elif choose == 3:
    set_answer()

elif choose == 4:
    set_name()

else:
    server_socket.close()
    exit(0)


server_socket.close()

#[]=========================================[]#




